#ifndef COMPUTEPARAMETER_H
#define COMPUTEPARAMETER_H

#include <QVector>
#include "commondefine.h"

class QPointF;
class LaneItem;
class RoadItem;

struct StateParameter
{
    double dZCoordinate = 999;  //z坐标
    std::string strTrackId = "999";  //道路ID
    int iLaneId = 999;  //车道ID
    double dSCoordinate = 999;  //S坐标
    double dTCoordinate = 999;  //T坐标
    double dLaneWidth = 999;  //车道宽度
    std::string strLaneRadius = "999";  //车道半径
    double dLaneOffset = 999;  //车道偏移
    std::string strLaneType = "999";  //车道类型
};

struct GeometryAttributes
{
    std::string strTrackId;  //道路ID
    int iLaneId;  //车道ID
    std::string strLaneType;  //车道类型
    std::string strGeometryType;
    double dGeometrySCoordinate;  //道路绝对S坐标
    double dLaneSectionSCoordinate;  //道路绝对S坐标
    double dGeometryXCoordinate;
    double dGeometryYCoordinate;
    double dGeometryHdg;
    double dGeometryLength;
    double dGeometryStartCurvature;
    double dGeometryEndCurvature;
    double dGeometryParameterA;
    double dGeometryParameterB;
    double dGeometryParameterC;
    double dGeometryParameterD;
    QVector<Width> qvecLaneWidth;
    QVector<SLaneOffset> qvecLaneOffset;
    QVector<SElevation> qvecElevation;
    Height height;
};

struct PointHdg
{
    QVector<QPointF> qvecPointData;
    QVector<double> qvecHdgData;
    QVector<double> qvecSData;
};

class ComputeParameter
{
public:
    ComputeParameter();
    ~ComputeParameter();

    StateParameter calculateLineParameter(GeometryAttributes *pGeometryAttributes, const QPointF &pointf);
    StateParameter calculateArcParameter(GeometryAttributes *pGeometryAttributes, const QPointF &pointf);
    StateParameter calculateSpiralParameter(GeometryAttributes *pGeometryAttributes, const QPointF &pointf);
    StateParameter calculatePoly3Parameter(GeometryAttributes *pGeometryAttributes, const QPointF &pointf);

    void calculateLineSTCoordinate(GeometryAttributes *pGeometryAttributes, const QPointF &pointf, StateParameter &lineParameter);
    void calculateArcSTCoordinate(GeometryAttributes *pGeometryAttributes, const QPointF &pointf, StateParameter &arcParameter);
    double calculateSpiralSTCoordinate(GeometryAttributes *pGeometryAttributes, const QPointF &pointf, StateParameter &spiralParameter);
    double calculatePoly3STCoordinate(GeometryAttributes *pGeometryAttributes, const QPointF &pointf, StateParameter &poly3Parameter);

    void calculateCommonParameter(GeometryAttributes *pGeometryAttributes, StateParameter &geometryParameter);

    double getMouseMovedPointDistance(PointHdg &pointHdg, const QPointF &pointf);
    double getPointCrossProduct(PointHdg &pointHdg, const QPointF &pointf);

    double getZCoordinate(GeometryAttributes *pGeometryAttributes, double dSCoordinate, StateParameter &stateParameter);
    double getLaneOffsetWidth(GeometryAttributes *pGeometryAttributes, double dSCoordinate);
    void getGeometryAttributes(RoadItem *pRoadItem, LaneItem *pLaneItem, GeometryAttributes *&pGeometryAttributes);  //得到对应的图元的信息

    StateParameter calculateParameter(RoadItem *pRoadItem, LaneItem *pLaneItem, const QPointF &pointf);  //计算状态参数

    void getDirectionAllLaneWidth(LaneItem *pLaneItem, GeometryAttributes *pGeometryAttributes);  //得到该方向上的所有车道宽度参数

    PointHdg geometrySpiralData(double dXCoordinate, double dYCoordinate, double dHdg, double dLength, double dCurvatureStart, double dCurvatureEnd, double dParameterVar);
    QPointF subFunctionSpiral(double dScaleFactorA, double dVarValue);
    void setPointAndHdg(double dCurvatureStart, double dCurvatureEnd, QVector<QPointF> &qvecGeometrySpiral, QVector<double> &qvecHdg);  //设置标准螺旋线上的数据点和切角
    void spinPoint(double dSpinHdg, QVector<QPointF> &qvecGeometrySpiral);  //旋转数据点
    void panPoint(double dXCoordinate, double dYCoordinate, QVector<QPointF> &qvecGeometrySpiral);  //平移数据点

    QPointF convertCoordinateSystem(GeometryAttributes *pGeometryAttributes, const QPointF &pointf);
    double computeDistanceSquareFirstDerivative(GeometryAttributes *pGeometryAttributes, QPointF &pointUVCoordinateSystem, double dUCoordinate);
    double computeDistanceSquareSecondDerivative(GeometryAttributes *pGeometryAttributes, double dMouseMovedVCoordinate, double dUCoordinate);
    double getVCoordinate(GeometryAttributes *pGeometryAttributes, double dUCoordinate);
    double getVCoordinateFirstDerivative(GeometryAttributes *pGeometryAttributes, double dUCoordinate);
    double getVCoordinateSecondDerivative(GeometryAttributes *pGeometryAttributes, double dUCoordinate);
    double getPoly3Curvature(GeometryAttributes *pGeometryAttributes, double dUCoordinate);

};

#endif // COMPUTEPARAMETER_H
